package dhc;


import robocode.ScannedRobotEvent;
import robocode.Robot;
import robocode.HitWallEvent;

/**
 * Searches for a target, moves perpendicular to the target while firing.
 * 
 * @author Daniel Colton
 */
public class MistaRoboto extends Robot {
  
  // Counter to keep in track of the radar sweep. 
  int counter = 0;
  // Defines the movement rate. 
  int move = 300;
  // Counts how many times the robot hit the walls. 
  int hitWallCount = 0;

  /**
   *  Move the robot forward and sweep for target.
   */
  public void run() {
    while (true) {
      ahead(move);
      if ((counter % 2) == 0) {
        turnRadarLeft(250);
      }
      else {
        turnRadarRight(250);
      }
    }
  }

  /**
   * Turns the tank perpendicular to the target on scan.
   * 
   * @param event is an instance of ScannedRobotEvent object.
   */
  public void onScannedRobot(ScannedRobotEvent event) {

    counter++;
    // Get the position of target in degrees.
    double targetHeading = getHeading() + event.getBearing();
    // Get the angular difference between Mistaroboto and the target. 
    double heading = getTurnAngle(getHeading(), targetHeading);
    // Get the angular difference between Mistaroboto's gun heading and the target. 
    double gunHeading = getTurnAngle(getGunHeading(), targetHeading);
    turnGunLeft(gunHeading);

    /**
     * Change fire power depending on how close the target is.
     */
    if (event.getDistance() < 200) {
      fire(3);
    }
    else if (event.getDistance() < 500) {
      fire(2);
    }
    if ((counter % 3) == 0) {
      fire(1);
    }
    // Check if tank is already pointed approximately perpendicular to the target. 
    // If not, rotate the tank. 
    if (!((Math.abs(heading) > 45) && (Math.abs(heading) < 135))) {
      // Rotate t
      if (heading < 0) {
        turnLeft(55);
      }
      else {
        turnRight(55);
      }
    }
  }

  /**
   * Revereses direction after hitting a wall. 
   * 
   * @param event is an instance of HitWallEvent object.
   */
  public void onHitWall(HitWallEvent event) {
    hitWallCount++;
    if (hitWallCount % 4 == 0) {
      turnLeft(90);
      ahead(250);
    }
    move = move * -1;
  }

  /**
   * Returns the difference in angle between the tank's heading and the target in degrees.
   * 
   * @param heading is the tank's current heading.
   * @param formatDegree is the direction of the target.
   * @return returns the angle difference in double.
   */
  public static double getTurnAngle(double heading, double formatDegree) {

    double resultDegree = heading - formatDegree;

    if (resultDegree > 180) {
      resultDegree = resultDegree - 360;
    }
    else if (resultDegree < -180) {
      resultDegree = 360 + resultDegree;
    }
    return resultDegree;
  }
}
